From 0a981dce1692e6796888c8a1c0eee4b8d65bd5db Mon Sep 17 00:00:00 2001 From: PacketFiend Date: Tue, 12 Sep 2023 07:28:55 -0400 Subject: [PATCH] Integrate OAT and SIU with Waypoints (#1060) * Integrate OAT and SIU with Waypoints * Type corrections, convert set_value() overload to nullptr* check * #1062 Fix core dump when merging tracks with disparate IGC extensions * Reduce `value` variable scope when writing SimpleArrays * Debug oopsie bugfix, fix core dump when merging IGC files with no extensions * Collapse redundant if statement * Fix brain fart * Eliminate igc_fsdata::has_value() * Fix subtle satellite count bug * Fix small sat count bug, and eliminate some ifdefs * Make some IGC exts override default WP members * Include IGC line-by-line debug info * Remove accidentally included file * delete obsolete macros --------- Co-authored-by: tsteven4 <13596209+tsteven4@users.noreply.github.com> --- defs.h | 4 +- igc.cc | 5 +- igc.h | 9 ++- kml.cc | 105 ++++++++++++++++++------------- kml.h | 6 ++ reference/realtime.kml | 22 +++++++ reference/track/92GV66G1.igc.kml | 5 ++ reference/track/92HV66G1.igc.kml | 5 ++ waypt.cc | 1 + 9 files changed, 114 insertions(+), 48 deletions(-) diff --git a/defs.h b/defs.h index 2a337c319..18fe9c0cf 100644 --- a/defs.h +++ b/defs.h @@ -261,13 +261,15 @@ public: trait_cadence(0), trait_power(0), trait_depth(0), - trait_temperature(0) {} + trait_temperature(0), + trait_sat(0) {} unsigned int trait_geocaches:1; unsigned int trait_heartrate:1; unsigned int trait_cadence:1; unsigned int trait_power:1; unsigned int trait_depth:1; unsigned int trait_temperature:1; + unsigned int trait_sat:1; }; /* diff --git a/igc.cc b/igc.cc index 1910f2915..c26814354 100644 --- a/igc.cc +++ b/igc.cc @@ -260,6 +260,9 @@ void IgcFormat::read() strcpy(trk_desc, HDRMAGIC HDRDELIM); while (true) { + if (global_opts.debug_level >= 8) { + printf(MYNAME ": Processing IGC file line %i\n", current_line); + } igc_rec_type_t rec_type = get_record(&ibuf); current_line++; QString ibuf_q = QString::fromUtf8(ibuf); @@ -372,7 +375,7 @@ void IgcFormat::read() for (const auto& [name, ext, start, len, factor] : ext_types_list) { double ext_data = ibuf_q.mid(start,len).toInt() / factor; - fsdata->set_value(ext, ext_data); + fsdata->set_value(ext, ext_data, pres_wpt); if (global_opts.debug_level >= 6) { printf(" %s:%f", qPrintable(name), ext_data); } diff --git a/igc.h b/igc.h index 8646c1a10..d0672811e 100644 --- a/igc.h +++ b/igc.h @@ -298,7 +298,8 @@ struct igc_fsdata : public FormatSpecificData { std::optional acz; // Z Acceleration std::optional gfo; // G Force? - bool set_value(IgcFormat::igc_ext_type_t type, double value) + // Stores all data as igc_fsdata + bool set_value(IgcFormat::igc_ext_type_t type, double value, Waypoint *wp = nullptr) { bool success = true; switch (type) { @@ -312,6 +313,9 @@ struct igc_fsdata : public FormatSpecificData { vat = value; break; case IgcFormat::igc_ext_type_t::ext_rec_oat: + if (wp){ + wp->set_temperature(value); + } oat = value; break; case IgcFormat::igc_ext_type_t::ext_rec_trt: @@ -324,6 +328,9 @@ struct igc_fsdata : public FormatSpecificData { fxa = value; break; case IgcFormat::igc_ext_type_t::ext_rec_siu: + if (wp) { + wp->sat = value; + } siu = value; break; case IgcFormat::igc_ext_type_t::ext_rec_acz: diff --git a/kml.cc b/kml.cc index f05d86aa2..159cde986 100644 --- a/kml.cc +++ b/kml.cc @@ -69,8 +69,6 @@ #define ICON_DIR ICON_BASE "track-directional/track-%1.png" // format string where next arg is rotational degrees. #define MYNAME "kml" -// #define INCLUDE_IGC_TRT // Generally not very useful to graph on Google Earth -// #define INCLUDE_IGC_SIU // Satellites in use, not entirely useful to graph void KmlFormat::kml_init_color_sequencer(unsigned int steps_per_rev) { @@ -1496,6 +1494,10 @@ void KmlFormat::kml_mt_simple_array(const route_head* header, writer->writeTextElement(QStringLiteral("gx:value"), wpt->temperature_has_value()? QString::number(wpt->temperature_value(), 'f', 1) : QString()); break; + case wp_field::sat: + writer->writeTextElement(QStringLiteral("gx:value"), wpt->sat >= 0? + QString::number(wpt->sat) : QString()); + break; case wp_field::igc_enl: case wp_field::igc_tas: case wp_field::igc_vat: @@ -1561,6 +1563,7 @@ void KmlFormat::kml_mt_hdr(const route_head* header) bool has_heartrate = false; bool has_temperature = false; bool has_power = false; + bool has_sat = false; bool has_igc_exts = false; bool has_igc_enl = false; bool has_igc_tas = false; @@ -1570,12 +1573,8 @@ void KmlFormat::kml_mt_hdr(const route_head* header) bool has_igc_fxa = false; bool has_igc_gfo = false; bool has_igc_acz = false; -#ifdef INCLUDE_IGC_SIU bool has_igc_siu = false; // Not very useful to graph -#endif -#ifdef INCLUDE_IGC_TRT // Not very useful to graph - bool has_igc_trt = false; -#endif + bool has_igc_trt = false; // Not very useful to graph // This logic is kind of inside-out for GPSBabel. If a track doesn't // have enough interesting timestamps, just write it as a LineString. @@ -1635,6 +1634,10 @@ void KmlFormat::kml_mt_hdr(const route_head* header) if (tpt->power) { has_power = true; } + // # of satellites can legitimately be zero, so -1 means no data in this case + if (tpt->sat >= 0) { + has_sat = true; + } if (fs_igc) { has_igc_exts = true; if (fs_igc->enl.has_value()) { @@ -1661,47 +1664,29 @@ void KmlFormat::kml_mt_hdr(const route_head* header) if (fs_igc->acz.has_value()) { has_igc_acz = true; } -#ifdef INCLUDE_IGC_SIU - if (fs_igc->siu.has_value()) { - has_igc_siu = true; + if constexpr(kIncludeIGCSIU) { + if (fs_igc->siu.has_value()) { + has_igc_siu = true; + } } -#endif -#ifdef INCLUDE_IGC_TRT - if (fs_igc->trt.has_value()) { - has_igc_trt = true; + if constexpr(kIncludeIGCTRT) { + if (fs_igc->trt.has_value()) { + has_igc_trt = true; + } } -#endif } } // This gets unwieldly if we check each individual igc extension, // hence the has_igc_exts flag. if (has_cadence || has_depth || has_heartrate || has_temperature || - has_power || has_igc_exts) { + has_power || has_sat || has_igc_exts) { + bool include_kmt_sats = true; + bool include_kmt_temperature = true; writer->writeStartElement(QStringLiteral("ExtendedData")); writer->writeStartElement(QStringLiteral("SchemaData")); writer->writeAttribute(QStringLiteral("schemaUrl"), QStringLiteral("#schema")); - if (has_cadence) { - kml_mt_simple_array(header, kmt_cadence, wp_field::cadence); - } - - if (has_depth) { - kml_mt_simple_array(header, kmt_depth, wp_field::depth); - } - - if (has_heartrate) { - kml_mt_simple_array(header, kmt_heartrate, wp_field::heartrate); - } - - if (has_temperature) { - kml_mt_simple_array(header, kmt_temperature, wp_field::temperature); - } - - if (has_power) { - kml_mt_simple_array(header, kmt_power, wp_field::power); - } - // Perhaps not the /best/ way to do this, but this if ladder // should only be evaluated once. if (has_igc_exts) { @@ -1713,6 +1698,7 @@ void KmlFormat::kml_mt_hdr(const route_head* header) } if (has_igc_oat) { kml_mt_simple_array(header, kmt_igc_oat, wp_field::igc_oat); + include_kmt_temperature = false; } if (has_igc_vat) { kml_mt_simple_array(header, kmt_igc_vat, wp_field::igc_vat); @@ -1729,16 +1715,41 @@ void KmlFormat::kml_mt_hdr(const route_head* header) if (has_igc_acz) { kml_mt_simple_array(header, kmt_igc_acz, wp_field::igc_acz); } -#ifdef INCLUDE_IGC_SIU - if (has_igc_siu) { - kml_mt_simple_array(header, kmt_igc_siu, igc_siu); + if constexpr(kIncludeIGCSIU) { + if (has_igc_siu) { + kml_mt_simple_array(header, kmt_igc_siu, wp_field::igc_siu); + include_kmt_sats = false; + } } -#endif -#ifdef INCLUDE_IGC_TRT - if (has_igc_trt) { - kml_mt_simple_array(header, kmt_igc_trt, igc_trt); + if constexpr(kIncludeIGCTRT) { + if (has_igc_trt) { + kml_mt_simple_array(header, kmt_igc_trt, wp_field::igc_trt); + } } -#endif + } + + if (has_cadence) { + kml_mt_simple_array(header, kmt_cadence, wp_field::cadence); + } + + if (has_depth) { + kml_mt_simple_array(header, kmt_depth, wp_field::depth); + } + + if (has_heartrate) { + kml_mt_simple_array(header, kmt_heartrate, wp_field::heartrate); + } + + if (has_temperature && include_kmt_temperature) { + kml_mt_simple_array(header, kmt_temperature, wp_field::temperature); + } + + if (has_power) { + kml_mt_simple_array(header, kmt_power, wp_field::power); + } + + if (has_sat && include_kmt_sats) { + kml_mt_simple_array(header, kmt_sat, wp_field::sat); } writer->writeEndElement(); // Close SchemaData tag @@ -1924,7 +1935,8 @@ void KmlFormat::write() traits->trait_cadence || traits->trait_power || traits->trait_temperature || - traits->trait_depth) { + traits->trait_depth || + traits->trait_sat) { writer->writeStartElement(QStringLiteral("Schema")); writer->writeAttribute(QStringLiteral("id"), QStringLiteral("schema")); @@ -1943,6 +1955,9 @@ void KmlFormat::write() if (traits->trait_depth) { kml_mt_array_schema(kmt_depth, "Depth", "float"); } + if (traits->trait_sat) { + kml_mt_array_schema(kmt_sat, "Satellites", "int"); + } writer->writeEndElement(); // Close Schema tag } diff --git a/kml.h b/kml.h index f11e2ebbd..505e7aeac 100644 --- a/kml.h +++ b/kml.h @@ -74,6 +74,7 @@ public: heartrate, temperature, power, + sat, igc_enl, // Engine Noise Level igc_tas, // True Airspeed igc_vat, // Compensated variometer (total energy) @@ -123,6 +124,7 @@ private: static constexpr const char* kmt_temperature = "temperature"; static constexpr const char* kmt_depth = "depth"; static constexpr const char* kmt_power = "power"; + static constexpr const char* kmt_sat = "satellites"; // Constants pertaining to IGC files would be better defined in either igc.h or formspec.h static constexpr const char* kmt_igc_enl = "Engine Noise"; static constexpr const char* kmt_igc_vat = "Ttl Enrg Vario"; @@ -135,6 +137,10 @@ private: static constexpr const char* kmt_igc_siu = "# Of Sats"; static constexpr const char* kmt_igc_acz = "Z Accel"; + // IGC option compile-time flags + static constexpr bool kIncludeIGCSIU = true; + static constexpr bool kIncludeIGCTRT = false; + /* Member Functions */ void kml_init_color_sequencer(unsigned int steps_per_rev); diff --git a/reference/realtime.kml b/reference/realtime.kml index 1eb65120f..11a914249 100644 --- a/reference/realtime.kml +++ b/reference/realtime.kml @@ -126,6 +126,9 @@ Depth + + Satellites + Wpt_8u4Dqkf @@ -280,6 +283,25 @@ 402.7 + + 6 + 8 + 6 + 3 + 12 + 11 + 3 + 4 + 10 + 4 + 10 + 9 + 8 + 9 + 2 + 3 + 5 + diff --git a/reference/track/92GV66G1.igc.kml b/reference/track/92GV66G1.igc.kml index 5e325be05..046376dfb 100644 --- a/reference/track/92GV66G1.igc.kml +++ b/reference/track/92GV66G1.igc.kml @@ -110,6 +110,11 @@ 6 + + + Temperature + + Tracks diff --git a/reference/track/92HV66G1.igc.kml b/reference/track/92HV66G1.igc.kml index 91600f937..e5957a366 100644 --- a/reference/track/92HV66G1.igc.kml +++ b/reference/track/92HV66G1.igc.kml @@ -110,6 +110,11 @@ 6 + + + Temperature + + Tracks diff --git a/waypt.cc b/waypt.cc index 30b255c73..e7f45e08c 100644 --- a/waypt.cc +++ b/waypt.cc @@ -74,6 +74,7 @@ void update_common_traits(const Waypoint* wpt) traits.trait_power |= wpt->power > 0; traits.trait_depth |= wpt->depth_has_value(); traits.trait_temperature |= wpt->temperature_has_value(); + traits.trait_sat |= wpt->sat >= 0; } void -- 2.30.2